package com.cs.test.mq.consumer;

import com.cs.test.mq.BaseConsumer;
import com.cs.test.mq.util.MessageHelper;
import com.cs.test.pojo.Mail;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.UnknownServiceException;

@Slf4j
@Component
public class MailConsumer implements BaseConsumer {



    @Override
    public void consume(Message message, Channel channel) throws IOException {
        Mail mail = MessageHelper.msgToObj(message,Mail.class);
        log.info("收到信息:{}",mail.toString());

        // 模拟发送短信
        long l = System.currentTimeMillis();
        computePi(40_000);
        long l1 = System.currentTimeMillis();
        long success = l1-l;
        log.info("发送短信耗时:{}",success);
        // 假如计算π耗时超过3秒 算失败,,,
        long valve = 3;
        if (success > valve){
            throw new UnknownServiceException("send mail error");
        }
    }


//    public static void main(String[] args) {
//        long l = System.currentTimeMillis();
//        System.out.println(computePi(40_000));
//        long l1 = System.currentTimeMillis();
//        System.out.println(l-l1);
//    }

    /** constants used in pi computation */
    private static final BigDecimal FOUR = BigDecimal.valueOf(4);
    public static BigDecimal computePi(int digits) {
        int scale = digits + 5;
        BigDecimal arctan1_5 = arctan(5, scale);
        BigDecimal arctan1_239 = arctan(239, scale);
        BigDecimal pi = arctan1_5.multiply(FOUR).subtract(
                arctan1_239).multiply(FOUR);
        return pi.setScale(digits,
                BigDecimal.ROUND_HALF_UP);
    }

    /** rounding mode to use during pi computation */
    private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN;

    /**
     * Compute the value, in radians, of the arctangent of
     * the inverse of the supplied integer to the specified
     * number of digits after the decimal point.  The value
     * is computed using the power series expansion for the
     * arc tangent:
     *
     * arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 +
     *     (x^9)/9 ...
     */
    public static BigDecimal arctan(int inverseX,
                                    int scale)
    {
        BigDecimal result, numer, term;
        BigDecimal invX = BigDecimal.valueOf(inverseX);
        BigDecimal invX2 =
                BigDecimal.valueOf(inverseX * inverseX);

        numer = BigDecimal.ONE.divide(invX,
                scale, roundingMode);

        result = numer;
        int i = 1;
        do {
            numer =
                    numer.divide(invX2, scale, roundingMode);
            int denom = 2 * i + 1;
            term =
                    numer.divide(BigDecimal.valueOf(denom),
                            scale, roundingMode);
            if ((i % 2) != 0) {
                result = result.subtract(term);
            } else {
                result = result.add(term);
            }
            i++;
        } while (term.compareTo(BigDecimal.ZERO) != 0);
        return result;
    }
}
